﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Allegro.TaskExecution;

namespace Allegro.Mathlib
{
    /// <summary>
    /// Method of computation
    /// </summary>
    public enum ComputationMethod : int
    {
        /// <summary>
        /// No computation
        /// </summary>
        None = 0,
        /// <summary>
        /// Direct computation using a direct formula
        /// </summary>
        DirectComputation = 1,
        /// <summary>
        /// Integration of a differential equation
        /// </summary>
        Integrate = 2
    }

    /// <summary>
    /// Delegate for doing computations on a context. Input is the context.
    /// Output should be to the context
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public delegate void ContextComputation(double x, IODEIntegrationContext context);

    /// <summary>
    /// Execution context interface
    /// </summary>
    public interface IODEIntegrationContext : IExecutionContext
    {
        /// <summary>
        /// Map variables by assigning the setters
        /// </summary>
        /// <param name="taskMap"></param>
        void BindVariables(ITaskMap taskMap);

        /// <summary>
        /// Bind current computation results
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        void BindInput(double x, double[] y);

        /// <summary>
        /// Bind derivatives y'(x) separately
        /// </summary>
        /// <param name="dydx"></param>
        void BindDerivatives(double[] dydx, bool[] integratedFlags);

        /// <summary>
        /// Unbind results
        /// </summary>
        void UnbindData();

        /// <summary>
        /// Bind parameters
        /// </summary>
        /// <param name="parameters"></param>
        void BindParameters(ITaskData parameters);

        /// <summary>
        /// True if 
        /// </summary>
        bool DataIsBound { get; }

        /// <summary>
        /// Current x value
        /// </summary>
        double x { get; }

        /// <summary>
        /// Current y vector
        /// </summary>
        double[] y { get; }

        /// <summary>
        /// Current dydx vector
        /// </summary>
        double[] dydx { get; }
    }
}
